/**
 * @Tick.as
 *
 * @author sodaChen mail:asframe@qq.com
 * @version 1.0
 * <br>Copyright (C), 2013 asFrame.com
 * <br>This program is protected by copyright laws.
 * <br>Program Name:ASFrame
 * <br>Date:2013-11-9
 */
package com.asframe.mgr
{
	import com.asframe.collections.maps.HashMap;
	import com.asframe.fun.FunListMap;
	import com.asframe.pattern.Singleton;
	import com.asframe.tick.ITick;
	import com.asframe.utils.VectorUtils;
	
	import flash.display.Shape;
	import flash.events.Event;

	/**
	 * 心跳对象，当添加了心跳 函数之后，会根据帧频进行有规律地跳动，直接容器不再有需要执行的函数。
	 * 自带了Timer功能，具备指定时间间隔和次数地进行执行回调函数。
	 * Date:2013-11-9
	 */
	public class TickMgr extends Singleton
	{
		private static var instance:TickMgr;

		/** 心跳机制的动力机 **/
		private var power:Shape;
		/** 心跳集合 **/
		private var tickList:Vector.<Function>;
		/** 正在跑的心跳集合 **/
		private var runTickList:Vector.<Function>;
		/** 主要用于过滤重复的添加检测 **/
		private var tickMap:HashMap;
		/** 下一帧执行一次的回调 **/
		private var nextFunMap:FunListMap;
		/** 正在跑心跳中 **/
		private var isRunning:Boolean
		


		/**
		 * 获取实例的静态方法实例
		 * @return
		 *
		 */
		public static function getInstance():TickMgr
		{
			if(instance == null)
			{
				instance = new TickMgr();
			}
			return instance;
		}

		public function TickMgr():void
		{
			power = new Shape();
			tickList = new Vector.<Function>();
			tickMap = new HashMap();
			nextFunMap = new FunListMap(true);
			power.addEventListener(Event.ENTER_FRAME,onEnterFrame);
		}

		/**
		 * 添加心跳函数
		 * @param fun
		 *
		 */
		public function addFun(fun:Function):void
		{
			if(tickMap.hasKey(fun))
				return ;
			//正在遍历，并且还没开始复制新的数组
			if(isRunning && (runTickList == tickList))
			{
				tickList = tickList.concat();
			}
			tickList.push(fun);
			tickMap.put(fun,fun);
		}
		/**
		 * 开始心跳
		 */
		public function start():void
		{
			power.addEventListener(Event.ENTER_FRAME,onEnterFrame);
		}
		/**
		 * 停止心跳
		 */
		public function stop():void
		{
			power.removeEventListener(Event.ENTER_FRAME,onEnterFrame);
		}
		/**
		 * 删除心跳函数
		 * @param fun
		 */
		public function removeFun(fun:Function):void
		{
			//正在遍历，并且还没开始复制新的数组
			if(isRunning && (runTickList == tickList))
			{
				tickList = tickList.concat();
			}
			tickMap.remove(fun);
			VectorUtils.removeItem(tickList,fun);
		}
		/**
		 * 添加实现ITick接口的实例进行心跳
		 * @param tick
		 *
		 */
		public function addTick(tick:ITick):void
		{
			addFun(tick.tick);
		}
		public function removeTick(tick:ITick):void
		{
			removeFun(tick.tick);
		}
		/**
		 * 在下一次心跳的时候才执行函数(异步执行回调函数)
		 * @param fun
		 * @param param
		 *
		 */
		public function nextTickExe(fun:Function,param:* = null,theThis:Object = null):void
		{
			if(param == null || param is Array)
				nextFunMap.addFun(fun,param,theThis);
			else
				nextFunMap.addFun(fun,[param],theThis);
		}
		private function onEnterFrame(event:Event):void
		{
			//执行上一次需要执行的函数
			if(nextFunMap.length > 0)
			{
				nextFunMap.executeFun();
			}
			isRunning = true;
			//引用另外保存起来，因为有添加或者删除的操作，会重新复制一份新的数组
			runTickList = tickList;
			var length:int = runTickList.length;
			for (var i:int = 0; i < length; i++)
			{
				runTickList[i]();
			}
			isRunning = false;
		}
	}
}

